﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;


namespace QQSideShowCreator {
	partial class MainForm {
		/// <summary>
		/// Initialize properties that make sense when the program is saving an image.
		/// </summary>
		private void InitializePictureSavingModule() {
			formatOutputFile = ImageFormat.Jpeg;
			sizeFileResolution = new Size(QQ_X * 2, QQ_Y * 2);
			escape_indexes = new List<int>();
		}

		protected void RenewProfileForSaving(int segment_x, int segment_y, int padding_x, int padding_y,
			int row_count, int col_count) {
			QQ_X = segment_x;
			QQ_Y = segment_y;
			QQ_PADDING_X = padding_x;
			QQ_PADDING_Y = padding_y;
			ROW_COUNT = row_count;
			COLUMN_COUNT = col_count;

			sizeFileResolution = new Size(QQ_X * 2, QQ_Y * 2);
		}

		// the type used to output the 8 photos
		internal ImageFormat formatOutputFile;
		internal Size sizeFileResolution;   // output size of an image, a single piece of source image only
		/// <summary>
		/// filename only, without path & extension
		/// </summary>
		internal string sFileSimpleName;

		/// <summary>
		/// The actual width of an image fragment in the QQ sideshow.
		/// </summary>
		int QQ_X;
		/// <summary>
		/// The actual height of an image fragment in the QQ album sideshow.
		/// </summary>
		int QQ_Y;
		/// <summary>
		/// The actual width of the horizontal padding between two columns of image fragments
		/// </summary>
		int QQ_PADDING_X;
		/// <summary>
		/// The actual height of the vertical padding between two rows of image fragments
		/// </summary>
		int QQ_PADDING_Y;
		/// <summary>
		/// The number of image fragments in a row
		/// </summary>
		int ROW_COUNT;
		/// <summary>
		/// The number of image fragments in a column
		/// </summary>
		int COLUMN_COUNT;

		/// <summary>
		/// The index of fragments which must be ignored.
		/// </summary>
		List<int> escape_indexes;
		/// <summary>
		/// Get or set the indexes of destination files that must be ignored.
		/// </summary>
		public List<int> IgnoredIndexes {
			get { return escape_indexes; }
			set { escape_indexes = value; }
		}

		protected void SavePictures() {
			// Output bitmap for each fragment of source image
			Bitmap output = new Bitmap(sizeFileResolution.Width, sizeFileResolution.Height);
			// the GDI+ object for output bitmap
			Graphics g = Graphics.FromImage(output);
			g.InterpolationMode = InterpolationMode.HighQualityBicubic;
			g.SmoothingMode = SmoothingMode.HighQuality;
			g.PixelOffsetMode = PixelOffsetMode.HighQuality;
			g.CompositingQuality = CompositingQuality.HighQuality;

			int zooming_time = pictureBox1.Width / ( QQ_X * COLUMN_COUNT );
			
			for ( int row = 0; row < ROW_COUNT; ++row ) {
				for ( int col = 0; col < COLUMN_COUNT; ++col ) {
					// check for ignoring files
					int index = COLUMN_COUNT * ROW_COUNT - 1 - row * COLUMN_COUNT - col;
					bool bEscaped = false;
					foreach ( int id in escape_indexes ) {
						if ( id == index ) {
							bEscaped = true;
							break;
						}
					};
					if (bEscaped)
						continue;

					// 1. The image at A-st row and B-st column has a top left point at
					//    ( (53+9)*2*B + TopLeft.X, (40+9)*2*A + TopLeft.Y ), where '2' is
					//    the times on which the size of the picturebox is larger than the QQ
					//    album original size. The coordinates are reputed on the source image.
					// 2. And also, view_size = source_size * scale, that is,
					//    source_size = view_size ÷ scale
					
					g.DrawImage(imgSource, new Rectangle(Point.Empty, sizeFileResolution),
						( QQ_X + QQ_PADDING_X ) * zooming_time * col / ZoomingScale + ViewPortTopLeft.X,
						( QQ_Y + QQ_PADDING_Y ) * zooming_time * row / ZoomingScale + ViewPortTopLeft.Y,
						QQ_X * zooming_time / ZoomingScale,
						QQ_Y * zooming_time / ZoomingScale,
						GraphicsUnit.Pixel);

					// then the single image is waiting to output
					output.Save(DefineOutputFilename(index), formatOutputFile);
				}
			}
		}

		/// <summary>
		/// Define what the output filenames are like.
		/// Extensions may vary when different output format is set up.
		/// </summary>
		/// <param name="index">The sequence number of a output file, descent.</param>
		/// <returns>The safe file name string only, with an extension but no path.</returns>
		private string DefineOutputFilename(int index) {
			string outputName;
			string sOutputFolder = textOutputFolder.Text;
			string safe_file_name = sFileSimpleName.Replace('.', '_');

			outputName = safe_file_name + '_' + index.ToString();

			if ( formatOutputFile == ImageFormat.Jpeg ) {
				outputName += ".jpg";
			} else if ( formatOutputFile == ImageFormat.Bmp ) {
				outputName += ".bmp";
			} else if ( formatOutputFile == ImageFormat.Gif ) {
				outputName += ".gif";
			} else if ( formatOutputFile == ImageFormat.Png ) {
				outputName += ".png";
			}

			return sOutputFolder + '\\' + outputName;
		}
	}
}